package com.beep.erp.common.base;

import android.content.res.ColorStateList;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.view.menu.MenuBuilder;
import android.view.Menu;
import android.view.View;

import com.afollestad.materialdialogs.MaterialDialog;
import com.beep.erp.R;
import com.beep.erp.common.dialog.DialogControl;
import com.beep.erp.common.utils.AppManager;
import com.beep.erp.common.utils.TUtil;
import com.beep.erp.common.widget.tips.DefaultTipsHelper;
import com.beep.erp.common.widget.tips.TipsHelper;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * FileName: BaseActivity
 * description:activity基类
 * Author: jolly
 * Date: 2016/9/12
 */
public abstract class BaseActivity< P extends BasePresenter,M> extends RxAppCompatActivity implements DialogControl {

    private final String packageNameUmeng = this.getClass().getName();
    private Unbinder unbinder;
    public M mModel;
    public P mPresenter;
    private boolean _isVisible;
    private MaterialDialog _waitDialog;
    protected abstract int getLayout();

    protected abstract void initView();

    private Method noteStateNotSavedMethod;
    private Object fragmentMgr;
    private String[] activityClassName = {"Activity", "FragmentActivity"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppManager.getAppManager().addActivity(this);
        setContentView(getLayout());//设置布局内容
        unbinder = ButterKnife.bind(this);  //初始化黄油刀控件绑定框架
        _isVisible = true;
        mPresenter = TUtil.getT(this, 0);
        mModel = TUtil.getT(this, 1);
        init(savedInstanceState);
        this.initView();//初始化视图

        if (this instanceof BaseView){
            mPresenter.setVM(this, mModel);
            mPresenter.mContext=this;
        }
        invokeFragmentManagerNoteStateNotSaved();
    }

    private void invokeFragmentManagerNoteStateNotSaved() {
        //java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return;
        }
        try {
            if (noteStateNotSavedMethod != null && fragmentMgr != null) {
                noteStateNotSavedMethod.invoke(fragmentMgr);
                return;
            }
            Class cls = getClass();
            do {
                cls = cls.getSuperclass();
            } while (!(activityClassName[0].equals(cls.getSimpleName())
                    || activityClassName[1].equals(cls.getSimpleName())));

            Field fragmentMgrField = prepareField(cls, "mFragments");
            if (fragmentMgrField != null) {
                fragmentMgr = fragmentMgrField.get(this);
                noteStateNotSavedMethod = getDeclaredMethod(fragmentMgr, "noteStateNotSaved");
                if (noteStateNotSavedMethod != null) {
                    noteStateNotSavedMethod.invoke(fragmentMgr);
                }
            }

        } catch (Exception ex) {
        }
    }

    private Field prepareField(Class<?> c, String fieldName) throws NoSuchFieldException {
        while (c != null) {
            try {
                Field f = c.getDeclaredField(fieldName);
                f.setAccessible(true);
                return f;
            } finally {
                c = c.getSuperclass();
            }
        }
        throw new NoSuchFieldException();
    }

    private Method getDeclaredMethod(Object object, String methodName, Class<?>... parameterTypes) {
        Method method = null;
        for (Class<?> clazz = object.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                method = clazz.getDeclaredMethod(methodName, parameterTypes);
                return method;
            } catch (Exception e) {
            }
        }
        return null;
    }

    protected TipsHelper createTipsHelper(View view) {
        return new DefaultTipsHelper(this, view);
    }


    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    protected void init(Bundle savedInstanceState) {}
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null)
            mPresenter.onDestroy();
        unbinder.unbind();
        AppManager.getAppManager().finishActivity();
    }

    @Override
    protected boolean onPrepareOptionsPanel(View view, Menu menu) {
        if (menu != null) {
            if (menu.getClass() == MenuBuilder.class) {
                try {
                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e) {
                    System.out.print(getClass().getSimpleName() + "onMenuOpened...unable to set icons for overflow menu" + e);
                }
            }
        }
        return super.onPrepareOptionsPanel(view, menu);
    }

    @Override
    public MaterialDialog showWaitDialog() {
        return showWaitDialog(R.string.loading);
    }

    @Override
    public MaterialDialog showWaitDialog(int resid) {
        return showWaitDialog(getString(resid));
    }

    @Override
    public MaterialDialog showWaitDialog(String text) {
        if (_isVisible) {
            if (_waitDialog == null) {
                _waitDialog= new  MaterialDialog.Builder(this)
                        .progress(true, 0)
                        .progressIndeterminateStyle(false)
                        .autoDismiss(false)
                        .cancelable(false)
                        .build();
            }
            if (_waitDialog != null) {
                _waitDialog.setContent(text);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    _waitDialog.getProgressBar().setIndeterminateTintList(ColorStateList.valueOf(getResources().getColor(R.color.primary)));
                }
                _waitDialog.show();
            }
            return _waitDialog;
        }
        return null;
    }
    @Override
    public void hideWaitDialog() {
        if (_isVisible && _waitDialog != null) {
            try {
                _waitDialog.dismiss();
                _waitDialog = null;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
